记录最近学习到的一道经典面试题
1.要求:输出55555
原理:JS是单线程,程序在主线程中执行,当遇到setTimeout,将其放入等待队列,等for循环执行完毕后,再将等待队列中的console.log(i)执行
1 | for (var i=0;i<5;i++) { |
2.要求:输出501234
利用自执行/立即执行方式,闭包
原理:i传给了立即执行函数,立即执行函数的参数j是从i传过来的,而立即执行中的函数setTimeout里面的函数参数j是父函数立即执行函数的参数,这样形成一个闭包。
1 | for (var i=0;i<5;i++) { |
3.要求:输出501234
函数方式
原理:与上一条一样的,还是闭包,只是将立即执行函数单独提到外面
1 | var output = function(i){ |
4.要求:输出401234
let方式
原理:作用域问题,let作为ES6新增命令,其涉及到的相关知识或许很多人也没搞清楚。
本来的js是没有块级作用域的,用var定义i时,虽然在for循环中定义,但在执行时,依然会被提升。当执行console.log(i)时,循环已经完成,这时的i=5;所以再去执行console.log(i),i=5,这也可以解释第一个为什么输出五个5。
而用let定义i,for每执行一次就生成一个块级作用域,给setTimeout
1 | var j=0 |
5.要求:输出012345
setTimeout
原理:利用输出时间改变输出顺序,按i递增而设置延时500*i
1 | for (var i=0;i<5;i++){ |
6.要求:输出012345
Promise+立即执行函数
原理:定义多个异步任务,Promise也是ES6新增的,可以说是一个重要的知识点了,立下flag有空了整理下相关知识。
1 | const tasks=[]; |
7.要求:输出012345
Promise+函数方式实现
1 | const tasks = [] |